<template>
  <el-dialog class="menu-dialog" v-bind="$attrs" v-on="$listeners">
    <div class="el-dialog-body-child">
      <div class="top-box">
        <div class="tips-box">
          <el-tag type="warning"
            >温馨提示：选择的页面菜单中，需选择其所有父级目录方可有效。</el-tag
          >
        </div>
        <div class="btn-box flex-c-s">
          <el-button type="primary" size="small" @click="foldOrCollapse">{{
            !isExpand ? "全部展开" : "全部折叠"
          }}</el-button>
          <el-button type="danger" size="small" @click="selectAllOrReversal">{{
            !isSelectAll ? "全部选中" : "全部不选"
          }}</el-button>
          <el-button type="warning" size="small" @click="toggleSelect"
            >全部反选</el-button
          >
          <el-button plain size="small" @click="reset">重 置</el-button>
          <el-input
            class="filter-input flex-grow"
            size="small"
            placeholder="输入关键字进行过滤"
            v-model="filterText"
          ></el-input>
        </div>
      </div>

      <xiaobu-tree
        ref="tree"
        class="permission-list"
        :filter-node-method="filterNode"
        :check-strictly="true"
        show-checkbox
        node-key="menuId"
        @expandChange="expandChange"
        @check-change="checkChange"
        :settings="defaultProps"
        :default-expand-all="isExpand"
        :data="menuOptions"
      ></xiaobu-tree>
    </div>
    <div slot="footer" class="dialog-footer">
      <template>
        <el-button @click="$emit('close')">关 闭</el-button>
        <el-button type="primary" @click="save">保 存</el-button>
      </template>
    </div>
  </el-dialog>
</template>
<script>
import XiaobuTree from "./xiaobu-tree/index.vue"
import { roleApi } from "@/api"
import { listArrToTreeArr } from "vue2-element-admin-plugin"
export default {
  name: "SelectMenu",
  components: {
    XiaobuTree
  },
  props: {
    roleId: {
      type: [String, Number],
      default: ""
    }
  },
  data() {
    return {
      filterText: "", // 菜单列表过滤条件
      menuOptions: [],
      defaultProps: {
        children: "children",
        label: "menuName"
      },
      isExpand: true, // 是否展开
      isSelectAll: false, // 是否选中所有
      currentMenuIds: [], // 记录最开始的值
      menuIds: [] // 选中的 菜单id
    }
  },
  watch: {
    filterText(val) {
      this.$refs.tree && this.$refs.tree.getTree().filter(val)
    },
    roleId(val) {
      if (val) {
        roleApi.getMenuIdsByRoleId({ roleId: val }).then((data) => {
          this.currentMenuIds = data.map((item) => item.menuId)
          this.menuIds = data.map((item) => item.menuId)
          this.$nextTick(() => {
            this.$refs.tree &&
              this.$refs.tree.getTree().setCheckedKeys(this.menuIds)
          })
        })
      }
    }
  },
  async created() {
    await this.getMenuList()
  },
  methods: {
    // 渲染最初始值
    reset() {
      this.$nextTick(() => {
        this.$refs.tree &&
          this.$refs.tree.getTree().setCheckedKeys(this.currentMenuIds)
      })
    },
    // 过滤树形数据
    filterNode(value, data) {
      if (!value) {
        return true
      }
      return data.menuName.indexOf(value) !== -1
    },
    // 保存角色菜单列表
    async save() {
      let isConfirm = true
      const roleIdList = this.$store.getters.roleIdList
      if (roleIdList.includes(this.roleId)) {
        await this.$modal
          .confirm("此操作将影响到您的权限，是否继续操作？")
          .catch((err) => {
            // 取消或者关闭
            isConfirm = false
          })
      }
      if (!isConfirm) {
        return
      }

      const params = {
        roleId: this.roleId,
        menuIds: this.menuIds
      }
      roleApi
        .setMenuIdsByRoleId(params)
        .then((data) => {
          if (roleIdList.includes(this.roleId)) {
            this.$store.dispatch("user/getUserInfo")
          }
          this.$modal.msgSuccess(data.msg)
          this.filterText = ""
          this.$emit("close")
        })
        .catch((err) => {
          this.$emit("close")
        })
    },
    // 获取菜单列表
    getMenuList() {
      this.menuOptions = listArrToTreeArr(this.$store.getters.allMenuList, this.$store.state.user.treeConfig)
    },
    /**
     * @description: 权限选项展开或者折叠时事件
     * @param {*}
     * @return {*}
     * @author: syx
     */
    expandChange() {
      setTimeout(() => {
        if (this.isExpand) {
          const isFoldAllFirstLevel = this.$refs.tree.judgeFoldAllFirstLevel() //是否折叠所有一级树
          if (isFoldAllFirstLevel) {
            this.isExpand = false
          }
        } else {
          const isExpandAllFirstLevel =
            this.$refs.tree.judgeExpandAllFirstLevel() //是否展开所有一级树
          if (isExpandAllFirstLevel) {
            this.isExpand = true
          }
        }
      }, 100)
    },
    /**
     * @description: 当前节点选中状态变化时
     * @param {*}
     * @return {*}
     * @author: syx
     */
    checkChange() {
      this.menuIds = this.$refs.tree.getTree().getCheckedKeys()
      setTimeout(() => {
        //如果是全选状态，即文字显示 全部不选  则判断是否已经全部未选中
        if (this.isSelectAll) {
          const isUnSelectAll = this.$refs.tree.judgeUnSelectAll()
          if (isUnSelectAll) {
            this.isSelectAll = false
          }
        } else {
          //如果是未全选状态，即文字显示 全部选中  则判断是否已经全部选中
          const isSelectAll = this.$refs.tree.judgeSelectAll()
          if (isSelectAll) {
            this.isSelectAll = true
          }
        }
      }, 300)
    },
    /**
     * @description: 点击展开或收起
     * @param {*}
     * @return {*}
     * @author: syx
     */
    foldOrCollapse() {
      if (this.isExpand) {
        this.$refs.tree.foldAll()
        this.isExpand = false
      } else {
        this.$refs.tree.expandAll()
        this.isExpand = true
      }
    },
    /**
     * @description: 全选或者全不选
     * @param {*}
     * @return {*}
     * @author: syx
     */
    selectAllOrReversal() {
      if (this.isSelectAll) {
        this.$refs.tree.unSelectAll()
        this.isSelectAll = false
      } else {
        this.$refs.tree.selectAll()
        this.isSelectAll = true
      }
    },
    /**
     * @description: 全部反选
     * @param {*}
     * @return {*}
     * @author: syx
     */
    toggleSelect() {
      this.$refs.tree.toggleSelectAll()
    }
  }
}
</script>
<style lang="scss" scoped></style>
